第33章 结构体与联合体
在C++中,结构体(Struct)和联合体(Union)是两种用户自定义的数据类型,用于将不同类型的数据组合在一起,方便数据的管理和操作。结构体适用于存储多个相关但不同类型的数据,而联合体则通过共享内存空间存储不同类型的数据。
33.1 结构体(Struct)
33.1.1 结构体的定义
结构体语法:
struct 结构体名{
成员类型1 成员名1;
成员类型2 成员名2;
// ...更多成员
};
示例:定义学生结构体
struct Student{
string name;//姓名
int age;//年龄
float score;//成绩
char gender;//性别('M'男,'F'女)
};
33.1.2 结构体变量的定义与初始化
- 定义结构体同时创建变量
struct Teacher{
string name;
int id;
} t1,t2;
- 先定义结构体,后创建变量
struct Student{
string name;
int age;
};
Student s1, s2;
- 初始化 顺序初始化:
Student s3 = {"张三", 18};
C++11指定成员初始化(顺序不限):
Student s4 = {.age = 19, .name = "李四"};
33.1.3 结构体成员访问
- 普通结构体变量:
.成员访问符 - 结构体指针:
->箭头访问符
struct Student{
string name;
int age;
};
int main(){
Student s={"王五", 20};
Student* p= &s;
// 普通变量访问
cout<<"姓名:"<<s.name<<",年龄:"<<s.age<<endl;
// 指针访问
cout<<"姓名:"<<p->name<<",年龄:"<<p->age;
s.age = 21;
p->name="赵六";
return 0;
}
33.1.4 结构体数组
多个结构体组成数组,每一个数组元素都是结构体:
struct Book {
string title;//书名
string author;//作者
float price;//价格
};
int main(){
Book books[3]={
{"C++ Primer", "Lippman", 89.0f},
{"算法导论","CLRS",128.0f},
{"编程珠玑","Bentley",59.0f}
};
for(int i=0;i<3;i++){
cout<<"书名:"<<books[i].title
<<",作者:"<<books[i]
<<",价格:"<<books[i].price<<endl;
}
return 0;
}
33.1.5 结构体作为函数参数/返回值
- 值传递:拷贝完整结构体副本
struct Point{
int x;
int y;
};
void printPoint(Point p){
cout<<"("<<p.x<<","<<p.y<<")";
}
- 引用传递:不拷贝,可修改原结构体
void movePoint(Point& p, int dx, int dy){
p.x += dx;
p.y += dy;
}
- 函数返回结构体
Point createPoint(int x, int y){
Point p={x,y};
return p;
}
int main(){
Point p=createPoint(3,4);
printPoint(p);
movePoint(p,2,5);
printPoint(p);
return 0;
}
33.1.6 结构体嵌套
结构体成员可以是另一个结构体,用于复杂数据描述:
struct Date{
int year;
int month;
int day;
};
struct Employee{
string id;
string name;
Date hireDate;//嵌套日期结构体
float salary;
};
int main(){
Employee emp={
"E001",
"张三",
{2020,3,15},
8000.0f
};
cout<<"入职日期:"
<<emp.hireDate.year<<"-"
<<emp.hireDate.month<<"-"
<<emp.hireDate.day;
return 0;
}
33.2 联合体(Union)
33.2.1 联合体定义
联合体所有成员共享同一块内存,同一时刻只能存储其中一个成员。 语法:
union 联合体名{
成员类型1 成员1;
成员类型2 成员2;
};
示例:
union Data{
int i;
float f;
char c;
};
33.2.2 联合体变量使用
int main(){
Data d;
d.i=100;
cout<<"d.i="<<d.i<<endl;
d.f=3.14f;
cout<<"d.f="<<d.f<<endl;
d.c='A';
cout<<"d.c="<<d.c<<endl;
return 0;
}
修改一个成员会覆盖内存中其他成员的值,其他成员读取无意义。
33.2.3 联合体内存大小
联合体占用内存等于最大成员的字节数。
union SizeTest{
char a;//1字节
int b;//4字节
double c;//8字节
};
// sizeof(SizeTest) = 8
33.2.4 联合体应用场景
- 节省内存:不同时刻只用一种数据;
- 二进制数据解析、底层类型内存查看; 示例:浮点数内存转整数查看
union Converter{
float f;
int i;
};
int main(){
Converter conv;
conv.f=3.14f;
cout<<conv.i;
return 0;
}
33.3 结构体与联合体核心区别
| 对比项 | 结构体 struct | 联合体 union |
|---|---|---|
| 内存分配 | 所有成员独立分配,内存叠加 | 所有成员共享同一块内存 |
| 存储特性 | 所有成员可同时存储有效值 | 同一时间仅一个成员有效 |
| 大小 | 所有成员内存之和(含对齐填充) | 等于最大成员字节数 |
| 使用场景 | 存储一组关联不同属性数据 | 同一内存复用,节省空间 |